package com.maddox.relax.adapter;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 自定义RecyclerView通用适配器
 * 支持多布局
 * 支持长按和普通点击事件
 *
 * @author qingli
 * @param <T> 加载的数据类型
 */
public abstract class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<CommonRecyclerAdapter.ViewHolder> {

    protected Context mContext;
    protected LayoutInflater mInflater;
    //总数据源
    protected List<T> mDatas;
    //每个Item的布局id
    private int mLayoutId;

    private MultiTypeSupport<T> multiTypeSupport;

    public CommonRecyclerAdapter(Context context, List<T> datas, int layoutId) {
        this.mContext = context;
        mInflater = LayoutInflater.from(mContext);
        this.mDatas = datas;
        this.mLayoutId = layoutId;
        if (mDatas == null)
            mDatas = new ArrayList<>();
    }

    /**
     *  添加一组数据
     */
    public void addDatas(Collection<? extends T> dataList) {
        this.mDatas.addAll(dataList);
        notifyItemRangeChanged(getItemCount(),dataList.size());
    }

    /**
     * 重新设置一组数据
     */
    public void resetData(Collection<? extends T> dataList){
        this.mDatas.clear();
        this.mDatas.addAll(dataList);
        notifyDataSetChanged();
    }

    /**
     * 添加一条新数据
     */
    public void addOneData(T data){
        this.mDatas.add(data);
        notifyItemInserted(getItemCount());
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //多布局
        if (multiTypeSupport != null) {
            mLayoutId = viewType;
        }
        //创建ViewHolder
        View itemView = mInflater.inflate(mLayoutId, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        //设置点击和长按事件
        if (mItemClickListener != null) {
            holder.itemView.setOnClickListener(v -> {
                mItemClickListener.onItemClick(holder.itemView, position, mDatas.get(position));
            });
        }
        if (mItemLongClickListener != null) {
            holder.itemView.setOnLongClickListener(v -> {
                mItemLongClickListener.onItemLongClick(holder.itemView, position, mDatas.get(position));
                return true;
            });
        }

        //绑定数据回传出去由子类实现
        convert(holder, mDatas.get(position));
    }


    protected abstract void convert(ViewHolder holder, T data);

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    @Override
    public int getItemViewType(int position) {
        //把数据和位置回调出去,由子类实现多布局设置的布局id,利用viewType字段传输布局
        if (multiTypeSupport != null) {
            return multiTypeSupport.getLayoutId(position, mDatas.get(position));
        }
        return super.getItemViewType(position);
    }

    /**
     * 支持多布局
     */
    public void setMultiTypeSupport(MultiTypeSupport<T> multiTypeSupport) {
        this.multiTypeSupport = multiTypeSupport;
    }

    private OnItemClickListener<T> mItemClickListener;
    private OnItemLongClickListener<T> mItemLongClickListener;

    /**
     * 条目点击事件
     */
    public void setOnItemClickListener(OnItemClickListener<T> listener) {
        this.mItemClickListener = listener;
    }

    /**
     * 条目长按事件
     */
    public void setItemLongClickListener(OnItemLongClickListener<T> listener) {
        this.mItemLongClickListener = listener;
    }

    public interface OnItemClickListener<T> {
        void onItemClick(View itemView, int position, T item);
    }

    public interface OnItemLongClickListener<T> {
        void onItemLongClick(View itemView, int position, T item);
    }

    /**
     * 数据缓存ViewHolder
     */
    static class ViewHolder extends RecyclerView.ViewHolder {


        private View itemView;
        private SparseArray<View> mViews;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            this.itemView = itemView;
            mViews = new SparseArray<>();
        }

        public <T extends View> T getView(int viewId) {
            View view = mViews.get(viewId);
            if (view == null) {
                view = itemView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return (T) view;
        }

        /**
         * 设置文本
         */
        public ViewHolder setText(int viewId, CharSequence character) {
            ((TextView) getView(viewId)).setText(character);
            return this;
        }

        /**
         * 设置图片
         */
        public ViewHolder setImageResource(int viewId, int resourceId) {
            ImageView imageView = getView(viewId);
            imageView.setImageResource(resourceId);
            return this;
        }

        /**
         * 设置Item中View可见性
         */
        public ViewHolder setViewVisibility(int viewId, int visibility) {
            getView(viewId).setVisibility(visibility);
            return this;
        }

        /**
         * 设置图片Url路径,考虑到三方加载图片框架的不同
         * 所以将ImageView和图片路径回调出去交给子Adapter实现
         */
        public ViewHolder setImageUrl(int viewId, String imageUrl, HolderImageLoader imageLoader) {
            ImageView imageView = getView(viewId);
            if (imageLoader == null) {
                throw new NullPointerException("HolderImageLoader is null !");
            }
            imageLoader.displayImage(imageView.getContext(), imageView, imageUrl);
            return this;
        }


    }

    /**
     * 图片加载抽象类
     */
    public static abstract class HolderImageLoader {
        private String mImageUrl;

        public HolderImageLoader(String imageUrl) {
            this.mImageUrl = mImageUrl;
        }

        public String getImagePath() {
            return mImageUrl;
        }

        public abstract void displayImage(Context context, ImageView imageView, String imageUrl);
    }

    /**
     * 多布局接口
     */
    public interface MultiTypeSupport<T> {

        int getLayoutId(int position, T item);
    }
}
